home *** CD-ROM | disk | FTP | other *** search
- /*
- xpk file (un)packer - special version for DirectoryOpus5 usage
-
-
- Copyright © 1995 by Daniel Balster
- */
-
- #include <exec/exec.h>
- #include <dos/dos.h>
- #include <libraries/xpk.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include <stdio.h>
- #include <string.h>
-
- #include <rexx/storage.h>
- #include <rexx/rxslib.h>
-
- struct Library *XpkBase;
-
- #define DEBUG 1
-
- #ifdef DEBUG
- void kprintf(UBYTE *fmt,...);
- #define bug kprintf
- #define D(X) X
- #else
- #define D(X)
- #endif
-
- #define AllocStruct(X) AllocVec(sizeof(struct X),MEMF_CLEAR|MEMF_PUBLIC)
- #define FreeStruct(X) FreeVec(X)
-
- #define ifnot(expr) if(!(expr))
-
- typedef enum { false=0, true=~(false) } bool;
-
- extern struct ExecBase *SysBase;
-
- LONG __regargs PackFile(struct DosLibrary *DOSBase,struct Library *XpkBase,
- char *,struct FileInfoBlock *,char *,char *,LONG,char *,LONG,LONG);
- LONG __regargs UnPackFile(struct DosLibrary *DOSBase,struct Library *XpkBase,
- char *,char *,struct FileInfoBlock *,char *);
- LONG __asm __saveds ChunkFunc(register __a1 struct XpkProgress *);
-
- /**************************/
-
- STRPTR lister;
- char dopus[32];
-
- char buffer[256];
-
- LONG __asm __saveds ChunkFunc(register __a1 struct XpkProgress *P)
- {
- char result[2];
-
- sprintf(buffer,
- "sys:rexxc/rx \"address %s;options results;"
- "lister set %s progress name '%s (%ld%% gain)';"
- "lister set %s progress count %ld;"
- "lister query %s abort;call export('%08lx'x,RESULT);\"",
- dopus,lister,P->Activity,P->CF,lister,P->Done,lister,result);
-
- if (!Execute (buffer,0,0)) return SIGBREAKF_CTRL_C;
- if (result[0]=='1') return SIGBREAKF_CTRL_C;
-
- return (LONG) SetSignal(0L,SIGBREAKF_CTRL_C)&SIGBREAKF_CTRL_C;
- }
-
- struct Hook ChunkHook = {{0L},ChunkFunc};
-
- /**************************/
-
- #define TAGIT(i,t,d) xtags[i].ti_Tag=t; xtags[i].ti_Data=(ULONG)d;
- #define ENDIT(i) xtags[i].ti_Tag=TAG_DONE;
-
- struct TagItem xtags[10];
- struct XpkFib xfib;
-
- char buf[108];
- char xpkerr[XPKERRMSGSIZE];
-
- void __regargs tmpname()
- {
- UWORD Index;
- ULONG Addr;
- for (Index=0, Addr=(ULONG)FindTask(NULL); Index<8; Index++, Addr>>=4) buf[Index] = 'A'+(char)(Addr&15);
- (void)strcpy(&buf[8],"..db");
-
- }
-
- #define ERR_PROTECTED (1)
- #define ERR_MINSIZE (2)
- #define ERR_XPK (3)
- #define ERR_UNPACKED (4)
- #define ERR_PACKED (5)
- #define ERR_NOGAIN (6)
- #define ERR_NODELETE (7)
- #define ERR_NOTRENAMED (8)
- #define ERR_EXAMINE (9)
- #define ERR_OPENFILE (10)
- #define ERR_MEMORY (11)
- #define ERR_ARGS (12)
- #define ERR_CURRENTDIR (13)
-
- STRPTR errors[] =
- {
- 0,
- "Source is DELETE protected (D-bit)",
- "File skipped because it is too small",
- 0,
- "File is already packed",
- "File is already unpacked",
- "Could not reach any gain",
- "Could not delete source file",
- "Could not rename destination as source",
- "Could not examine source file",
- "Could not open source file",
- "Internal memory allocation failed",
- "Could not parse the arguments",
- "Could not lock the source directory"
- };
-
- LONG xpack(struct FileInfoBlock *fib,BPTR file,STRPTR lib,STRPTR passwd,LONG minsize)
- {
- ULONG size;
-
- if (fib->fib_Protection&FIBF_DELETE) return ERR_PROTECTED;
- if (fib->fib_Size<=minsize) return ERR_MINSIZE;
-
- TAGIT(0,XPK_GetError,xpkerr);
- TAGIT(1,XPK_InFH,file);
- ENDIT(2);
- if (XpkExamine(&xfib,xtags)) return ERR_XPK;
- if (xfib.Type!=XPKTYPE_UNPACKED) return ERR_UNPACKED;
-
- tmpname();
-
- TAGIT(0,XPK_Password,passwd);
- TAGIT(1,XPK_GetError,xpkerr);
- TAGIT(2,XPK_FindMethod,lib);
- TAGIT(3,XPK_ChunkHook,&ChunkHook);
- TAGIT(4,XPK_FileName,fib->fib_FileName);
- TAGIT(5,XPK_InFH,file);
- TAGIT(6,XPK_OutName,buf);
- TAGIT(7,XPK_GetOutLen,&size);
- ENDIT(8);
-
- if (XpkPack(xtags)) return ERR_XPK;
-
- if (size>fib->fib_Size) { DeleteFile(buf);return ERR_NOGAIN; }
-
- return 0l;
- }
-
- LONG xunpack(struct FileInfoBlock *fib,BPTR file,STRPTR passwd)
- {
- if (fib->fib_Protection&FIBF_DELETE) return ERR_PROTECTED;
-
- TAGIT(0,XPK_GetError,xpkerr);
- TAGIT(1,XPK_InFH,file);
- ENDIT(2);
- if (XpkExamine(&xfib,xtags)) return ERR_XPK;
- if (xfib.Type!=XPKTYPE_PACKED) return ERR_PACKED;
-
- tmpname();
-
- TAGIT(0,XPK_Password,passwd);
- TAGIT(1,XPK_GetError,xpkerr);
- TAGIT(2,XPK_ChunkHook,&ChunkHook);
- TAGIT(3,XPK_FileName,fib->fib_FileName);
- TAGIT(4,XPK_InFH,file);
- TAGIT(5,XPK_OutName,buf);
- ENDIT(6);
-
- if (XpkUnpack(xtags)) return ERR_XPK;
-
- return 0;
- }
-
- #define TMPLATE "DIR/A/K,FILE/A/K,LIB=METHOD/K,PASSWD/K,PACK/S,MINSIZE/N/K,LISTER/A/K,REXXPORT/A/K"
-
- struct {
- STRPTR dirname;
- STRPTR filename;
- STRPTR libname;
- STRPTR passwd;
- ULONG pack;
- ULONG* minsize;
- STRPTR handle;
- STRPTR dopus;
- } args = {0};
-
- LONG main()
- {
- struct RDArgs *rda;
- struct FileInfoBlock *fib;
- BPTR file;
- LONG err=100;
-
- if (!(XpkBase=OpenLibrary(XPKNAME,2l))) return 20;
-
- if(rda = ReadArgs(TMPLATE,(LONG*)&args,0))
- {
- BPTR olddir,dir;
-
- if (dir = Lock(args.dirname,ACCESS_READ))
- {
- olddir = CurrentDir(dir);
- if (fib = AllocVec(sizeof(*fib),MEMF_CLEAR|MEMF_PUBLIC))
- {
- if (file = Open(args.filename,MODE_OLDFILE))
- {
- if (ExamineFH(file,fib))
- {
- ULONG mz;
-
- if (args.minsize) mz = *args.minsize;
- else mz = fib->fib_Size-1;
-
- lister = args.handle;
- strcpy(dopus,args.dopus);
-
- if (args.pack)
- err = xpack(fib,file,args.libname,args.passwd,mz);
- else
- err = xunpack(fib,file,args.passwd);
- }
- else err = ERR_EXAMINE;
- Close(file);
-
- if (err==0)
- {
- if (fib->fib_Comment[0]) SetComment(buf,fib->fib_Comment);
- if (fib->fib_Protection) SetProtection(buf,fib->fib_Protection);
- SetFileDate(buf,&fib->fib_Date);
- if (!DeleteFile(fib->fib_FileName)) err = ERR_NODELETE;
- if (!Rename(buf,fib->fib_FileName)) err = ERR_NOTRENAMED;
- }
- }
- else err = ERR_OPENFILE;
- FreeVec(fib);
- }
- else err = ERR_MEMORY;
-
- CurrentDir(olddir);
- UnLock(dir);
- }
- else err = ERR_CURRENTDIR;
-
- FreeArgs(rda);
- }
- else err = ERR_ARGS;
-
- if (err)
- {
- char ebuf[128];
-
- if (err==ERR_XPK)
- sprintf(ebuf,"rx \"address %s;dopus request '''%s''' 'Ok'\"",dopus,xpkerr);
- else
- sprintf(ebuf,"rx \"address %s;dopus request '''Error: %s''' 'Ok'\"",dopus,errors[err]);
-
- Execute(ebuf,0,0);
- }
-
- return 0;
- }
-
-